#include "main.h"

// 声明互斥锁变量
pthread_mutex_t client_array_mutex;

// 定义客户端结构体数组，存储所有连接的客户端信息
ClientData clients[MAX_CLIENT];

int main(int argc, char const *argv[])
{
    // 判断命令行参数
    if (argc < 2)
    {
        printf("参数错误:%s ip port\n", argv[0]);
        return -1;
    }

    // 初始化TCP服务器
    int Socket_fd = TCP_init(atoi(argv[1]));

    // 初始化数据库
    sqlite3 *db = sqlite3_init_log_in();

    char name[128];
    char password[128];
    char buf[128];

    // 存储客户端连接的个数
    int Acce_fds[MAX_CLIENT];
    // 存储客户端线程的个数
    pthread_t client_threads[MAX_CLIENT];

    // 初始化客户端连接的个数   -1表示没有连接
    for (int i = 0; i < MAX_CLIENT; i++)
    {
        Acce_fds[i] = -1;
    }

    // 初始化互斥锁
    pthread_mutex_init(&client_array_mutex, NULL);

    while (1)
    {
        // 等待客户端连接
        int Acce_fd = TCP_accept(Socket_fd);

        // 查找空闲的客户端位置
        int index = -1;
        for (int i = 0; i < MAX_CLIENT; i++)
        {
            if (Acce_fds[i] == -1)
            {
                index = i;
                break;
            }
        }

        if (index != -1)
        {
            Acce_fds[index] = Acce_fd;

            // 清空
            memset(name, 0, sizeof(name));
            memset(password, 0, sizeof(password));
            memset(buf, 0, sizeof(buf));

            strcpy(buf, "请输入1(登录)或2(注册)\n");
            send(Acce_fd, buf, strlen(buf), 0);

            if (recv(Acce_fd, buf, sizeof(buf), 0) <= 0)
            {
                perror("接收错误");
                close(Socket_fd);
                close(Acce_fd);
                sqlite3_close(db);
                return EOF;
            }
            int choice = atoi(buf);
            // 判断是登录还是注册
            switch (choice)
            {
            case 1:
                strcpy(buf, "请输入要登录的用户名和密码\n");
                send(Acce_fd, buf, strlen(buf), 0);
                // 接收用户名和密码
                if (recv(Acce_fd, name, sizeof(name), 0) <= 0 || recv(Acce_fd, password, sizeof(password), 0) <= 0)
                {
                    perror("接收错误");
                    close(Socket_fd);
                    close(Acce_fd);
                    sqlite3_close(db);
                    return EOF;
                }
                // 登录
                if (!log_in(db, name, password))
                {
                    strcpy(buf, "登录失败，请重新输入选择\n");
                    send(Acce_fd, buf, strlen(buf), 0);
                    printf("登录失败\n");
                }
                else
                {
                    strcpy(buf, "登录成功\n");
                    send(Acce_fd, buf, strlen(buf), 0);
                    printf("登录成功\n");
                }
                break;
            case 2:
                strcpy(buf, "请输入要注册的用户名和密码\n");
                send(Acce_fd, buf, strlen(buf), 0);
                // 接收用户名和密码
                if (recv(Acce_fd, name, sizeof(name), 0) <= 0 || recv(Acce_fd, password, sizeof(password), 0) <= 0)
                {
                    perror("接收错误");
                    close(Socket_fd);
                    close(Acce_fd);
                    sqlite3_close(db);
                    return EOF;
                }
                // 注册
                if (!Register(db, name, password))
                {
                    strcpy(buf, "注册失败，请重新输入选择\n");
                    send(Acce_fd, buf, strlen(buf), 0);
                    printf("注册失败\n");
                }
                else
                {
                    strcpy(buf, "注册成功\n");
                    send(Acce_fd, buf, strlen(buf), 0);
                    printf("注册成功\n");
                }
                break;
            default:
                break;
            }

            // 接受新的客户端连接
            int new_client_fd = TCP_accept(Socket_fd);
            if (new_client_fd < 0)
            {
                perror("Accept error");
                continue;
            }

            // 创建客户端数据结构并传递给线程
            ClientData *client_data = (ClientData *)malloc(sizeof(ClientData));
            client_data->socket_fd = new_client_fd;
            client_data->db = db;

            // 将新连接的客户端信息添加到数组中
            pthread_mutex_lock(&client_array_mutex);
            for (int i = 0; i < MAX_CLIENT; i++)
            {
                if (clients[i].socket_fd == -1)
                {
                    clients[i] = *client_data;
                    break;
                }
            }
            pthread_mutex_unlock(&client_array_mutex);

            // 创建线程
            pthread_create(&client_threads[index], NULL, chat_thread, client_data);
            // 线程分离态
            pthread_detach(client_threads[index]);
        }
        else
        {
            // 没有空闲位置
            strcpy(buf, "服务器已满，请稍后再试\n");
            send(Acce_fd, buf, strlen(buf), 0);
            close(Acce_fd);
        }
    }

    // 关闭套接字和数据库连接
    close(Socket_fd);
    sqlite3_close(db);

    // 销毁互斥锁
    pthread_mutex_destroy(&client_array_mutex);

    return 0;
}
